package com.pt.controller;

import com.pt.common.ApiResponse;
import com.pt.common.CommonResult;
import com.pt.dto.request.UpdateProfileRequest;
import com.pt.dto.request.ChangePasswordRequest;
import com.pt.dto.request.UserUpdateRequest;
import com.pt.dto.request.UserSettingsRequest;
import com.pt.dto.response.UserStatsResponse;
import com.pt.dto.response.UserProfileResponse;
import com.pt.dto.response.UserSettingsResponse;
import com.pt.entity.User;
import com.pt.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import com.pt.common.Result;
import com.pt.model.request.LoginRequest;
import com.pt.security.JwtTokenProvider;
import org.springframework.beans.factory.annotation.Autowired;
import com.pt.util.SecurityUtils;
import com.pt.common.enums.UserClass;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@RestController
@RequestMapping("/api/user")
@Api(value = "用户接口", tags = "用户接口", description = "用户个人资料相关的API接口")
public class UserController {
    
    private final UserService userService;
    private final JwtTokenProvider tokenProvider;
    
    private static final String AVATAR_DIRECTORY = "D:\\api_homework\\my_pt\\avatars\\";
    
    private static final Logger log = LoggerFactory.getLogger(UserController.class);
    
    @Autowired
    public UserController(UserService userService, JwtTokenProvider tokenProvider) {
        this.userService = userService;
        this.tokenProvider = tokenProvider;
    }
    
    @GetMapping("/profile")
    @PreAuthorize("hasRole('USER')")
    @ApiOperation(value = "获取当前用户信息", notes = "获取当前登录用户的个人资料信息")
    public ApiResponse<Map<String, Object>> getProfile() {
        User user = userService.getCurrentUser();
        
        // 创建响应对象，包含passkey（仅对自己可见）
        Map<String, Object> userProfile = new HashMap<>();
        userProfile.put("id", user.getId());
        userProfile.put("username", user.getUsername());
        userProfile.put("email", user.getEmail());
        userProfile.put("status", user.getStatus());
        userProfile.put("userClass", user.getUserClass());
        userProfile.put("uploaded", user.getUploaded());
        userProfile.put("downloaded", user.getDownloaded());
        userProfile.put("bonusPoints", user.getBonusPoints());
        userProfile.put("invitationCode", user.getInvitationCode());
        userProfile.put("invitedBy", user.getInvitedBy());
        userProfile.put("passkey", user.getPasskey()); // 只在个人资料中暴露
        userProfile.put("createdTime", user.getCreatedTime());
        userProfile.put("lastLoginTime", user.getLastLoginTime());
        userProfile.put("lastLoginIp", user.getLastLoginIp());
        userProfile.put("avatar", user.getAvatar());
        userProfile.put("signature", user.getSignature());
        userProfile.put("assessmentDeadline", user.getAssessmentDeadline());
        userProfile.put("warningCount", user.getWarningCount());
        // 添加计算字段
        userProfile.put("shareRatio", user.getShareRatio());
        
        return ApiResponse.success(userProfile);
    }
    
    @PutMapping("/profile")
    @PreAuthorize("hasRole('USER')")
    @ApiOperation(value = "更新用户个人资料", notes = "更新当前用户的个人资料信息")
    public CommonResult<User> updateProfile(@RequestBody UserUpdateRequest request) {
        User user = userService.getCurrentUser();
        if (request.getEmail() != null) {
            user.setEmail(request.getEmail());
        }
        if (request.getBio() != null) {
            user.setSignature(request.getBio());
        }
        userService.updateUser(user);
        return CommonResult.success(user);
    }
    
    @PutMapping("/password")
    @PreAuthorize("hasRole('USER')")
    @ApiOperation(value = "修改密码", notes = "修改当前用户的登录密码")
    public CommonResult<String> changePassword(@RequestBody ChangePasswordRequest request) {
        userService.changeUserPassword(request);
        return CommonResult.success("密码修改成功");
    }
    
    @GetMapping("/stats")
    @PreAuthorize("hasRole('USER')")
    @ApiOperation("获取用户统计信息")
    public ApiResponse<UserStatsResponse> getUserStats() {
        Long userId = SecurityUtils.getCurrentUserId();
        UserStatsResponse stats = userService.getUserStats(userId);
        return ApiResponse.success(stats);
    }
    
    @GetMapping("/daily-download-limit")
    public ApiResponse<Integer> getDailyDownloadLimit() {
        Long userId = SecurityUtils.getCurrentUserId();
        User user = userService.getById(userId);
        if (user == null) {
            return ApiResponse.error("用户不存在");
        }
        
        // 获取用户等级
        UserClass userClass = UserClass.getByCode(user.getUserClass());
        if (userClass == null) {
            log.error("用户等级无效 - 用户ID: {}, 等级: {}", userId, user.getUserClass());
            return ApiResponse.error("用户等级无效");
        }
        
        // 获取用户等级对应的下载限制
        Integer limit = userClass.getDailyDownloadLimit();
        
        // 如果是无限制，直接返回-1
        if (limit == -1) {
            return ApiResponse.success(-1);
        }
        
        // 获取今日已下载次数
        Integer dailyCount = userService.getDailyDownloadCount(userId);
        
        // 返回剩余下载次数
        return ApiResponse.success(Math.max(0, limit - dailyCount));
    }
    
    @PostMapping("/regenerate-passkey")
    @PreAuthorize("hasRole('USER')")
    @ApiOperation(value = "重新生成Passkey", notes = "重新生成用户的Passkey，用于客户端连接")
    public CommonResult<String> regeneratePasskey() {
        String newPasskey = userService.regeneratePasskey();
        return CommonResult.success(newPasskey);
    }
    
    @GetMapping("/profile/{userId}")
    @ApiOperation("获取用户公开资料")
    public ApiResponse<UserProfileResponse> getUserProfile(@PathVariable Long userId) {
        try {
            System.out.println("=== 获取用户公开资料 ===");
            System.out.println("请求的用户ID: " + userId);
            
            // 获取当前查看者ID
            User currentUser = userService.getCurrentUser();
            Long viewerId = currentUser != null ? currentUser.getId() : null;
            
            UserProfileResponse profile = userService.getUserProfile(userId, viewerId);
            System.out.println("获取用户资料成功: " + profile.getUsername());
            
            return ApiResponse.success(profile);
        } catch (Exception e) {
            System.out.println("获取用户资料失败: " + e.getMessage());
            e.printStackTrace();
            return ApiResponse.error("获取用户资料失败: " + e.getMessage());
        }
    }

    @PostMapping("/upload-avatar")
    @PreAuthorize("hasRole('USER')")
    @ApiOperation(value = "上传头像", notes = "上传用户头像")
    public CommonResult<String> uploadAvatar(@RequestParam("file") MultipartFile file) {
        if (file.isEmpty()) {
            return CommonResult.error("请选择要上传的头像文件");
        }

        // 检查文件类型
        String contentType = file.getContentType();
        if (contentType == null || !contentType.startsWith("image/")) {
            return CommonResult.error("只能上传图片文件");
        }

        // 检查文件大小（限制为2MB）
        if (file.getSize() > 2 * 1024 * 1024) {
            return CommonResult.error("头像文件大小不能超过2MB");
        }

        try {
            // 确保头像目录存在
            File directory = new File(AVATAR_DIRECTORY);
            if (!directory.exists()) {
                directory.mkdirs();
            }

            // 生成唯一文件名
            String originalFilename = file.getOriginalFilename();
            String fileExtension = "";
            if (originalFilename != null && originalFilename.contains(".")) {
                fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
            }
            String filename = UUID.randomUUID().toString() + fileExtension;
            
            // 保存文件
            File targetFile = new File(directory, filename);
            file.transferTo(targetFile);

            // 更新用户头像URL
            User user = userService.getCurrentUser();
            String avatarUrl = "/avatars/" + filename;
            user.setAvatar(avatarUrl);
            userService.updateUser(user);

            return CommonResult.success(avatarUrl);
        } catch (IOException e) {
            return CommonResult.error("头像上传失败：" + e.getMessage());
        }
    }
    
    @GetMapping("/settings")
    @PreAuthorize("hasRole('USER')")
    @ApiOperation(value = "获取用户设置", notes = "获取当前用户的通知和隐私设置")
    public CommonResult<UserSettingsResponse> getUserSettings() {
        UserSettingsResponse settings = userService.getUserSettings();
        return CommonResult.success(settings);
    }
    
    @PutMapping("/settings")
    @PreAuthorize("hasRole('USER')")
    @ApiOperation(value = "保存用户设置", notes = "保存当前用户的通知和隐私设置")
    public CommonResult<String> saveUserSettings(@RequestBody @Valid UserSettingsRequest request) {
        userService.saveUserSettings(request);
        return CommonResult.success("设置保存成功");
    }

    @PostMapping("/login")
    public Result<User> login(@RequestBody LoginRequest request) {
        User user = userService.login(request.getUsername(), request.getPassword());
        if (user != null) {
            // 更新最后登录时间
            userService.updateLastLogin(user.getId());
            // 生成token
            String token = tokenProvider.generateToken(user.getId());
            user.setToken(token);
            return Result.success(user);
        }
        return Result.error("用户名或密码错误");
    }

    @PutMapping("/users/{userId}/admin")
    @PreAuthorize("hasRole('ADMIN')")
    public Result<Void> updateUserAdminStatus(@PathVariable Long userId, @RequestBody Map<String, Boolean> request) {
        // 不允许修改ID为1的用户的管理员身份
        if (userId == 1) {
            return Result.error("不能修改超级管理员的管理员身份");
        }
        
        Boolean isAdmin = request.get("isAdmin");
        if (isAdmin == null) {
            return Result.error("参数错误");
        }
        
        userService.updateUserAdminStatus(userId, isAdmin);
        return Result.<Void>success(null);
    }
} 